#include "../../Base/stdafx.h"
#include "Box.h"
#include "../../Base/Light.h"
#include "../../Base/vertex.h"
#include "../../PhysX/PhysX.h"
#include "../../Effects/EffectShadow.h"
#include "../MeshHelper.h"


void Box::Draw()
{
	m_Mesh->DrawSubset(0);
}

void Box::Init( const MeshDesc& mDesc )
{
	m_MeshDesc = mDesc;
	this->GetTotalTranspose();
	// NXActor
	NxActorDesc ActorDesc;
	D3DXComputeBoundingBox(&m_VertexList[0].m_Pos, m_VertexList.size(), sizeof(Vertex), &m_BoundingBox.minPt, &m_BoundingBox.maxPt);

	NxBoxShapeDesc BoxShapeDesc;
	D3DXVECTOR3 BBSize = m_BoundingBox.size();
	BoxShapeDesc.dimensions = NxVec3(BBSize.x / 2, BBSize.y/2, BBSize.z/2);
	BoxShapeDesc.mass = BBSize.x * BBSize.y * BBSize.z;
	ActorDesc.shapes.push_back(&BoxShapeDesc);
	NxMat34 mat;
	mat.setColumnMajor44(m_World);

	if(mDesc.state == MeshDesc::PhysxDynamic)
	{
		NxBodyDesc bodyDesc;
		bodyDesc.angularDamping	= 0.9f;
		bodyDesc.linearVelocity = NxVec3(0,0,0);
		//bodyDesc.mass = BBSize.x * BBSize.y * BBSize.z;
		ActorDesc.body = &bodyDesc;
	}

	ActorDesc.globalPose = mat;
	ActorDesc.density = 10.0f;

	m_Actor = PhysX::GetSingleton()->GetScene()->createActor(ActorDesc);

	HR(m_Mesh->SetVertexData(0, &m_VertexList[0]));
	HR(m_Mesh->SetIndexData(&m_IndexList[0], m_IndexList.size()));

	HR(m_Mesh->GenerateAdjacencyAndPointReps(0.001f));
	HR(m_Mesh->Optimize(D3DX10_MESHOPT_ATTR_SORT | D3DX10_MESHOPT_VERTEX_CACHE, 0, 0));
	HR(m_Mesh->GenerateGSAdjacency());
	HR(m_Mesh->CommitToDevice());

	if(m_TextureFile.size() != 0) {
		HR(D3DX10CreateShaderResourceViewFromFile(DXDEVICE->GetDevice(), m_TextureFile.c_str(), NULL, NULL, &m_Texture, NULL));
	}else{
		HR(D3DX10CreateShaderResourceViewFromFile(DXDEVICE->GetDevice(), _T("./Textures/WhiteTex.dds"), NULL, NULL, &m_Texture, NULL));
	}
	if(m_NormalTex.length() > 0)
		HR(D3DX10CreateShaderResourceViewFromFile(GETDEVICE, m_NormalTex.c_str(), NULL, NULL, &m_NormalMap, NULL));
	if(m_SpecTex.length() > 0)
		HR(D3DX10CreateShaderResourceViewFromFile(GETDEVICE, m_SpecTex.c_str(), NULL, NULL, &m_SpecMap, NULL));
}

const ID3D10ShaderResourceView* Box::GetTexture() const
{
	return m_Texture;
}

Box::Box( const MeshDesc& mDesc, const D3DXVECTOR3& pos, float width, float length, float height): m_NormalMap(0), m_SpecMap(0)
{
	tstring file = mDesc.name;
	m_TextureFile = mDesc.diffuseMap;
	m_NormalTex = mDesc.normalMap;
	m_SpecTex = mDesc.specMap;
	Counter mCounter; mCounter.Start();
	
	float vertx = width / 2;
	float verty = length / 2;
	float vertz = height / 2;
	// Bovenvlak
	m_VertexList.push_back(Vertex(D3DXVECTOR3(-vertx, vertz, -verty), D3DXVECTOR3(0, 1, 0), D3DXVECTOR2(0, 1), D3DXVECTOR3(0, 0, 0)));
	m_VertexList.push_back(Vertex(D3DXVECTOR3(-vertx, vertz, verty), D3DXVECTOR3(0, 1, 0), D3DXVECTOR2(0, 0), D3DXVECTOR3(0, 0, 0)));
	m_VertexList.push_back(Vertex(D3DXVECTOR3(vertx, vertz, verty), D3DXVECTOR3(0, 1, 0), D3DXVECTOR2(1, 0), D3DXVECTOR3(0, 0, 0)));
	m_VertexList.push_back(Vertex(D3DXVECTOR3(vertx, vertz, -verty), D3DXVECTOR3(0, 1, 0), D3DXVECTOR2(1, 1), D3DXVECTOR3(0, 0, 0)));

	// Ondervlak
	m_VertexList.push_back(Vertex(D3DXVECTOR3(-vertx, -vertz, -verty), D3DXVECTOR3(0, -1, 0), D3DXVECTOR2(0, 1), D3DXVECTOR3(0, 0, 0)));
	m_VertexList.push_back(Vertex(D3DXVECTOR3(vertx, -vertz, -verty), D3DXVECTOR3(0, -1, 0), D3DXVECTOR2(0, 0), D3DXVECTOR3(0, 0, 0)));
	m_VertexList.push_back(Vertex(D3DXVECTOR3(vertx, -vertz, verty), D3DXVECTOR3(0, -1, 0), D3DXVECTOR2(1, 0), D3DXVECTOR3(0, 0, 0)));
	m_VertexList.push_back(Vertex(D3DXVECTOR3(-vertx, -vertz, verty), D3DXVECTOR3(0, -1, 0), D3DXVECTOR2(1, 1), D3DXVECTOR3(0, 0, 0)));

	// Voorkant
	m_VertexList.push_back(Vertex(D3DXVECTOR3(-vertx, -vertz, -verty), D3DXVECTOR3(0, 0, -1), D3DXVECTOR2(0, 1), D3DXVECTOR3(0, 0, 0)));
	m_VertexList.push_back(Vertex(D3DXVECTOR3(-vertx, vertz, -verty), D3DXVECTOR3(0, 0, -1), D3DXVECTOR2(0, 0), D3DXVECTOR3(0, 0, 0)));
	m_VertexList.push_back(Vertex(D3DXVECTOR3(vertx, vertz, -verty), D3DXVECTOR3(0, 0, -1), D3DXVECTOR2(1, 0), D3DXVECTOR3(0, 0, 0)));
	m_VertexList.push_back(Vertex(D3DXVECTOR3(vertx, -vertz, -verty), D3DXVECTOR3(0, 0, -1), D3DXVECTOR2(1, 1), D3DXVECTOR3(0, 0, 0)));

	// Achterkant
	m_VertexList.push_back(Vertex(D3DXVECTOR3(vertx, -vertz, verty), D3DXVECTOR3(0, 0, 1), D3DXVECTOR2(0, 1), D3DXVECTOR3(0, 0, 0)));
	m_VertexList.push_back(Vertex(D3DXVECTOR3(vertx, vertz, verty), D3DXVECTOR3(0, 0, 1), D3DXVECTOR2(0, 0), D3DXVECTOR3(0, 0, 0)));
	m_VertexList.push_back(Vertex(D3DXVECTOR3(-vertx, vertz, verty), D3DXVECTOR3(0, 0, 1), D3DXVECTOR2(1, 0), D3DXVECTOR3(0, 0, 0)));
	m_VertexList.push_back(Vertex(D3DXVECTOR3(-vertx, -vertz, verty), D3DXVECTOR3(0, 0, 1), D3DXVECTOR2(1, 1), D3DXVECTOR3(0, 0, 0)));

	// Linkerkant
	m_VertexList.push_back(Vertex(D3DXVECTOR3(-vertx, -vertz, verty), D3DXVECTOR3(-1, 0, 0), D3DXVECTOR2(0, 1), D3DXVECTOR3(0, 0, 0)));
	m_VertexList.push_back(Vertex(D3DXVECTOR3(-vertx, vertz, verty), D3DXVECTOR3(-1, 0, 0), D3DXVECTOR2(0, 0), D3DXVECTOR3(0, 0, 0)));
	m_VertexList.push_back(Vertex(D3DXVECTOR3(-vertx, vertz, -verty), D3DXVECTOR3(-1, 0, 0), D3DXVECTOR2(1, 0), D3DXVECTOR3(0, 0, 0)));
	m_VertexList.push_back(Vertex(D3DXVECTOR3(-vertx, -vertz, -verty), D3DXVECTOR3(-1, 0, 0), D3DXVECTOR2(1, 1), D3DXVECTOR3(0, 0, 0)));

	// Rechterkant
	m_VertexList.push_back(Vertex(D3DXVECTOR3(vertx, -vertz, -verty), D3DXVECTOR3(0, 1, 0), D3DXVECTOR2(0, 1), D3DXVECTOR3(0, 0, 0)));
	m_VertexList.push_back(Vertex(D3DXVECTOR3(vertx, vertz, -verty), D3DXVECTOR3(0, 1, 0), D3DXVECTOR2(0, 0), D3DXVECTOR3(0, 0, 0)));
	m_VertexList.push_back(Vertex(D3DXVECTOR3(vertx, vertz, verty), D3DXVECTOR3(0, 1, 0), D3DXVECTOR2(1, 0), D3DXVECTOR3(0, 0, 0)));
	m_VertexList.push_back(Vertex(D3DXVECTOR3(vertx, -vertz, verty), D3DXVECTOR3(0, 1, 0), D3DXVECTOR2(1, 1), D3DXVECTOR3(0, 0, 0)));

	m_IndexList.push_back(0); m_IndexList.push_back(1); m_IndexList.push_back(2);
	m_IndexList.push_back(0); m_IndexList.push_back(2); m_IndexList.push_back(3);
	
	m_IndexList.push_back(4); m_IndexList.push_back(5); m_IndexList.push_back(6);
	m_IndexList.push_back(4); m_IndexList.push_back(6); m_IndexList.push_back(7);

	m_IndexList.push_back(8); m_IndexList.push_back(9); m_IndexList.push_back(10);
	m_IndexList.push_back(8); m_IndexList.push_back(10); m_IndexList.push_back(11);

	m_IndexList.push_back(12); m_IndexList.push_back(13); m_IndexList.push_back(14);
	m_IndexList.push_back(12); m_IndexList.push_back(14); m_IndexList.push_back(15);

	m_IndexList.push_back(16); m_IndexList.push_back(17); m_IndexList.push_back(18);
	m_IndexList.push_back(16); m_IndexList.push_back(18); m_IndexList.push_back(19);

	m_IndexList.push_back(20); m_IndexList.push_back(21); m_IndexList.push_back(22);
	m_IndexList.push_back(20); m_IndexList.push_back(22); m_IndexList.push_back(23);

	for(size_t t = 0; t < m_IndexList.size(); t += 3)
	{
		MeshHelper::CalculateTangent(m_VertexList.at(m_IndexList.at(t)), m_VertexList.at(m_IndexList.at(t + 1)), m_VertexList.at(m_IndexList.at(t + 2)));
	}

	D3D10_INPUT_ELEMENT_DESC Layout[] =
	{
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
		{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0},
		{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D10_INPUT_PER_VERTEX_DATA, 0},
		{ "TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 32, D3D10_INPUT_PER_VERTEX_DATA, 0},
	};

	HR(D3DX10CreateMesh(GETDEVICE, Layout, 4, Layout[0].SemanticName, m_VertexList.size(), m_IndexList.size()/3, D3DX10_MESH_32_BIT, &m_Mesh));

	SetTranslate(pos);

	Init(mDesc);

	mCounter.Stop();
	LOG(_T("Box ingelaad. Totale tijd: ") + mCounter.GetTime());
}

Box::~Box()
{
	m_Mesh->Release();
	m_Texture->Release();
	if(m_NormalMap) m_NormalMap->Release();
	if(m_SpecMap) m_SpecMap->Release();
}

const ID3D10ShaderResourceView* Box::GetNormalMap() const
{
	return m_NormalMap;
}

const ID3D10ShaderResourceView* Box::GetSpecularMap() const
{
	return m_SpecMap;
}